#include <iostream>
#include <functional>
#include <string>
using namespace std;

int func(int a, int b){
    std::cout << "a = " << a << ", b = " << b << std::endl;
    return a + b;
}

class A{
    public:
        int mem_func(int a, int b, int c){
            std::cout << "a = " << a << ", b = " << b << ", c =" << c<< std::endl;
            return a + b + c;
        }
        void fun()
        {
            auto s1 = bind(&A::mem_func, this, 1, std::placeholders::_1, 5);
            s1(10);
        }
};
int main(){
    //直接生成一个可调用对象，然后调用，参数为3
    //bind(func, 1, std::placeholders::_1)中表示将参数1 和参数 std::placeholders::_1作为函数func的参数，绑定成另一个可执行对象。
    //在绑定的时候， 按照顺序，1 作为 func(int a, int b) 中形参a的实参； std::placeholders::_1 作为 func(int a, int b) 中形参b的实参

    //std::placeholders::_1 是占位符，表示将绑定后得到的可执行对象进行调用的时候，实参的第1个，放到 std::placeholders::_1的位置上去
    //依次，std::placeholders::_2 将调用的时候实参的第2个，放到该位置上去
    //注意，占位符 std::placeholders::_x 中x必须小于等于调用的时候实际参数的个数！！
    std::bind(func, 1, std::placeholders::_1)(3);       //输出 a = 1, b = 3
    std::bind(func, 1, std::placeholders::_2)(3, 6);    //输出 a = 1, b = 6

    //用function可调用对象f保存bind后的结果
    std::function<int(int)> f = std::bind(func, 1, std::placeholders::_1);
    f(2);       //输出 a = 1, b = 2
    f = std::bind(func, std::placeholders::_1, 1); 
    f(3);       //输出 a = 3, b = 1

    //将类的非静态成员函数，以及类的对象实例，进行绑定
    A a;
    auto f1 = std::bind(&A::mem_func, a, std::placeholders::_3, std::placeholders::_1, std::placeholders::_2);
    f1(10, 20, 30);
    a.fun();
    return 0;
}
